1 00:00:00,540 --> 00:00:02,580 With the introduction of if statements. 2 00:00:02,580 --> 00:00:08,460 There's another fundamental concept in programming I'd like to cover called lexical scope. 3 00:00:08,490 --> 00:00:14,970 Lexical scope, also called scope for short, is a region in your code where a particular variable or 4 00:00:14,970 --> 00:00:18,480 identifier is visible and can be accessed. 5 00:00:18,510 --> 00:00:23,280 Scope determines which variables our interpreter can see and interact with. 6 00:00:23,310 --> 00:00:29,220 A great example would be to imagine a building with multiple rooms and each room containing a window. 7 00:00:29,250 --> 00:00:34,320 You can imagine the interpreter as someone walking outside the building and looking through the window 8 00:00:34,320 --> 00:00:35,250 in each room. 9 00:00:35,280 --> 00:00:40,320 Each room represents a different scope that our interpreter can look into. 10 00:00:40,350 --> 00:00:46,800 For example, one room can be a kitchen and our interpreter can see knives, food, and other stuff 11 00:00:46,800 --> 00:00:48,030 relating to the kitchen. 12 00:00:48,060 --> 00:00:53,880 However, if our interpreter walks to the next window and sees a bathroom inside, it can no longer 13 00:00:53,910 --> 00:00:56,940 see the stuff inside of the kitchen like the knives in the food. 14 00:00:56,970 --> 00:01:01,860 Instead, it sees an entirely new scope with different stuff inside of it. 15 00:01:02,160 --> 00:01:08,370 To demonstrate scope, I'm going to create a new variable called where am I? 16 00:01:08,400 --> 00:01:11,100 So we can do where am I? 17 00:01:11,220 --> 00:01:15,510 And for now I'm going to set this equal to a string like the bathroom. 18 00:01:16,180 --> 00:01:16,600 Now. 19 00:01:16,600 --> 00:01:22,750 By default, this variable is accessible within the entire scope of our script. 20 00:01:22,780 --> 00:01:25,870 This is also known as the global scope. 21 00:01:25,900 --> 00:01:33,310 To restrict a variable to a specific scope, we use something called the local keyword in Lua. 22 00:01:33,460 --> 00:01:40,030 So before we create the identifier for our variable, we can type out the local keyword. 23 00:01:40,030 --> 00:01:45,910 And now we have restricted this variable to the scope where it was created. 24 00:01:46,000 --> 00:01:52,930 Now doing this and doing this is the same thing, because we're both declaring the variable within the 25 00:01:52,930 --> 00:01:56,860 entire global scope of the script, so there's no difference in doing it. 26 00:01:56,890 --> 00:02:03,820 However, using the local keyword is absolutely crucial to help us see where variables are being created 27 00:02:03,820 --> 00:02:09,520 or instantiated, and differentiate that from where values inside of our variable is being overridden. 28 00:02:09,550 --> 00:02:13,720 For example, here we know that a variable is being created. 29 00:02:13,720 --> 00:02:19,990 But if I do something like this and I set the value inside of where am I to something like kitchen. 30 00:02:20,290 --> 00:02:22,660 We aren't creating a variable here. 31 00:02:22,660 --> 00:02:27,670 Instead, what we're doing is we're referring to the already existing variable that we've created up 32 00:02:27,670 --> 00:02:33,040 here, and we're overriding the value inside of it to be equal to this new string right here. 33 00:02:33,040 --> 00:02:39,400 So this isn't creating a variable, it's simply overriding the value inside of a variable that was already 34 00:02:39,400 --> 00:02:40,280 created. 35 00:02:40,300 --> 00:02:47,050 But if we never use the local keyword, it can kind of be difficult to see where we're creating our 36 00:02:47,050 --> 00:02:52,030 variable and where we are overriding the value inside of our variable. 37 00:02:52,180 --> 00:02:59,530 So using the local keyword is a great practice to help us read our code more easily and see exactly 38 00:02:59,530 --> 00:03:06,820 where variables are being created, and where variables are having the values inside of them be overridden 39 00:03:06,820 --> 00:03:08,560 with a new value. 40 00:03:09,080 --> 00:03:12,650 Now, what I'm going to do is I'm going to create an if statement. 41 00:03:13,390 --> 00:03:19,630 And I'm going to check if the value inside of where am I is equal to something like the bathroom. 42 00:03:20,170 --> 00:03:26,320 If it is, then we're going to have the interpreter hop inside of this block of code right here, which 43 00:03:26,320 --> 00:03:28,300 is a brand new scope. 44 00:03:28,300 --> 00:03:35,050 And we know this is a brand new scope because the N keyword has popped up here to denote the end of 45 00:03:35,050 --> 00:03:36,330 a new scope. 46 00:03:36,340 --> 00:03:38,200 So this is our new scope in here. 47 00:03:38,200 --> 00:03:41,350 You can imagine this as another room inside of our building. 48 00:03:41,350 --> 00:03:44,050 And what I'm going to do in here is I'm going to create another variable. 49 00:03:44,050 --> 00:03:46,840 And I'm going to call this variable like knife. 50 00:03:46,840 --> 00:03:49,870 And I'm going to set it equal to a string like sharp. 51 00:03:49,870 --> 00:03:51,330 We'll just do something like that. 52 00:03:51,340 --> 00:03:58,270 Now to restrict this variable inside of this if statement block or this scope, I'm going to put the 53 00:03:58,270 --> 00:03:59,680 local keyword. 54 00:03:59,710 --> 00:04:03,100 This means anywhere outside of this block of code. 55 00:04:03,100 --> 00:04:05,890 I cannot see this knife variable. 56 00:04:05,920 --> 00:04:12,160 If I try to type out knife here, the interpreter is not going to have any idea what I'm talking about. 57 00:04:12,160 --> 00:04:20,200 If I got rid of that local keyword and I type out knife now it is able to see knife and I can autofill 58 00:04:20,200 --> 00:04:21,310 it automatically. 59 00:04:21,310 --> 00:04:26,440 But if I put the local keyword I have now restricted knife to this particular scope. 60 00:04:26,920 --> 00:04:32,350 We can also add another else if statement here and pass another condition so we can check if where am 61 00:04:32,350 --> 00:04:32,920 I. 62 00:04:33,100 --> 00:04:35,620 Let's say we're in the kitchen. 63 00:04:35,830 --> 00:04:44,740 So if the string inside of where am I is equal to kitchen, then inside of here we can create a toilet. 64 00:04:44,770 --> 00:04:46,480 Or actually now I have it flipped around. 65 00:04:46,480 --> 00:04:53,230 We should create the knife inside of the kitchen and then we'll create the toilet inside of the bathroom. 66 00:04:53,230 --> 00:04:54,190 My mistake. 67 00:04:54,370 --> 00:04:58,720 And we'll just set this equal to a string like flush or something like that. 68 00:04:59,620 --> 00:05:02,460 And now we have two completely different scopes. 69 00:05:02,470 --> 00:05:06,230 We have one scope here and we have one scope here. 70 00:05:06,250 --> 00:05:10,990 Neither of these scopes can see the other variable created in the other scope. 71 00:05:10,990 --> 00:05:14,470 So for example in this scope here I can't see toilet. 72 00:05:14,500 --> 00:05:16,180 It doesn't exist for me. 73 00:05:16,420 --> 00:05:24,490 And inside of this scope here I can't see knife A because I'm not in the same scope, and B the variable 74 00:05:24,490 --> 00:05:29,530 is created after the interpreter executes this code up here. 75 00:05:29,530 --> 00:05:32,860 So it's technically impossible to see this knife variable. 76 00:05:32,890 --> 00:05:40,690 But just for the sake of explanation, these two scopes have no idea of the other stuff in the other 77 00:05:40,690 --> 00:05:41,550 scope, right? 78 00:05:41,560 --> 00:05:46,240 If I'm in the bathroom, I don't know about the knife in the kitchen, and if I'm in the kitchen, I 79 00:05:46,240 --> 00:05:49,120 have no idea about the toilet in the bathroom. 80 00:05:49,120 --> 00:05:55,450 And if I am outside of both of those rooms, then I have no idea of neither the knife or the toilets 81 00:05:55,450 --> 00:05:56,140 existence. 82 00:05:56,140 --> 00:05:56,410 Right? 83 00:05:56,410 --> 00:06:02,200 If I type out knife, it doesn't know, and if I type out toilet, it doesn't know about that either. 84 00:06:02,200 --> 00:06:10,870 So this is the main idea of scope, where we restrict or hide variables and identifiers to their particular 85 00:06:10,870 --> 00:06:11,560 scope. 86 00:06:11,650 --> 00:06:15,970 It is always a good practice to use the local keyword. 87 00:06:15,970 --> 00:06:20,590 When you are creating your variables, you always want to restrict your variables to the scope that 88 00:06:20,590 --> 00:06:22,120 they belong inside of. 89 00:06:22,580 --> 00:06:28,640 So understanding and implementing lexical scope is absolutely critical for writing maintainable and 90 00:06:28,640 --> 00:06:30,050 bug free code. 91 00:06:30,080 --> 00:06:35,480 It helps to prevent unintended interactions between variables, and it also ensures that variables are 92 00:06:35,480 --> 00:06:37,520 accessible where they are needed. 93 00:06:37,550 --> 00:06:43,820 It's always best practice to use the local keyword when you are creating a variable to ensure that the 94 00:06:43,820 --> 00:06:47,390 only exist within their respective scopes. 95 00:06:47,420 --> 00:06:53,840 Now, one last very important thing I'd like to mention with lexical scope is how different variables 96 00:06:53,840 --> 00:06:58,700 take higher precedence over other variables, depending on what scope you're in. 97 00:06:58,790 --> 00:07:02,280 You might not understand what I mean, but I'm going to show you it here in a moment. 98 00:07:02,300 --> 00:07:06,110 So if I got rid of the local keyword here for my where am I? 99 00:07:06,140 --> 00:07:08,540 Variable and left it as default. 100 00:07:08,540 --> 00:07:11,030 So it's global to the entire script, right. 101 00:07:11,060 --> 00:07:14,150 We access where am I and check to see if we're in the bathroom. 102 00:07:14,150 --> 00:07:18,440 If we're in the bathroom, then what I'm going to do in here is I'm going to create a new variable. 103 00:07:18,440 --> 00:07:24,320 I'm going to use the local keyword, but this time I'm going to use the exact same name as this variable 104 00:07:24,320 --> 00:07:24,770 here. 105 00:07:24,770 --> 00:07:32,270 So if I do where am I and set this equal to something else like let's say I am, let's say I'm in the 106 00:07:32,270 --> 00:07:33,170 toilet, right? 107 00:07:34,020 --> 00:07:35,620 Let's just do something like that. 108 00:07:35,640 --> 00:07:39,360 And then I go and print out where am I here? 109 00:07:39,360 --> 00:07:44,190 And then I go down to the bottom of my script and print out where am I? 110 00:07:44,340 --> 00:07:48,210 What do you think is going to print in these two if statements? 111 00:07:48,240 --> 00:07:53,040 Well, we can go ahead and run the game and quickly figure this out. 112 00:07:53,040 --> 00:07:54,810 So if we hit run here. 113 00:07:57,360 --> 00:08:02,850 The first print statement printed out toilet, but the second print statement printed out bathroom. 114 00:08:02,880 --> 00:08:04,290 Interesting, right? 115 00:08:05,250 --> 00:08:07,050 So if we go back into our script. 116 00:08:07,080 --> 00:08:12,930 This first one here printed out toilet and this second one here printed out bathroom. 117 00:08:13,170 --> 00:08:19,440 Now this is because since we created a new variable in here, even though it has the exact same name, 118 00:08:19,440 --> 00:08:23,370 these two variables are actually being treated as different. 119 00:08:23,370 --> 00:08:26,130 So we created this new local variable. 120 00:08:26,130 --> 00:08:27,660 Even though it has the same name. 121 00:08:27,660 --> 00:08:35,190 This variable takes higher precedence over this variable out here because we are inside of this scope. 122 00:08:35,190 --> 00:08:41,190 So when we use this print statement we are actually referring to this locally created where am I variable 123 00:08:41,190 --> 00:08:43,350 and not this globally created? 124 00:08:43,350 --> 00:08:44,330 Where am I variable. 125 00:08:44,340 --> 00:08:50,520 However, outside of that particular bathroom scope, when we use the print statement down here, we 126 00:08:50,520 --> 00:08:53,730 print out the bathroom string as expected. 127 00:08:53,730 --> 00:08:59,540 But of course up in here, since this local variable took higher precedent, it printed out toilet. 128 00:08:59,550 --> 00:09:04,170 So that's a very important thing you have to understand with scope is that when you create variables 129 00:09:04,170 --> 00:09:09,810 with the same name but restrict them to their scopes, they will take higher precedence over any other 130 00:09:09,810 --> 00:09:14,460 variables that were created in a more, you know, global scope. 131 00:09:14,460 --> 00:09:20,580 Now, you will usually never run into this problem because a you should never, ever name your variables 132 00:09:20,580 --> 00:09:21,630 the exact same thing. 133 00:09:21,630 --> 00:09:26,580 You should always give them a different name, because if you name variables the same thing, you're 134 00:09:26,580 --> 00:09:28,290 just bound to run into problems. 135 00:09:28,290 --> 00:09:34,380 But this is just a quick example of how the interpreter executes and sets the priority for different 136 00:09:34,380 --> 00:09:37,800 variables depending on the scope that they're created in. 137 00:09:38,040 --> 00:09:40,410 See you in the next lecture.